using Microsoft.AspNetCore.Http;
using XKPlatform.Common;
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using XKPlatform.DataModels;
using XKPlatform.Common.Enums;
//using MQHelper;
using Newtonsoft.Json;
//using MQHelper.MQ;
using System.Threading;
using XKPlatform.DataModels.Dao;
using System.Threading.Tasks;
using XKPlatform.Common.Const;
using XKPlatform.DataModels.Dao.BaseDao;
using XKPlatform.DataModels.DBHelper;
using FreeSql;
using Microsoft.AspNetCore.Http.Internal;

namespace XKPlatform.Common
{
    public class LogHelper
    {
        private static string lockKey = "lock";

        //当前环境
        public static EnvEnum Env = EnvEnum.DEV;
        //项目名称
        public static string ProjectName = "";
        //是否使用队列
        public static bool isUsingMQ = false;
        //队列类型
        //public static MqEnum mqType = MqEnum.rabbitmq;
        //存储类型
        public static LogSaveTypeEnum saveType = LogSaveTypeEnum.Console;
        /// <summary>
        /// 异常日志
        /// </summary>
        /// <param name="ex"></param>
        public static void SaveLog(Exception exception)
        {

            string error = string.Empty;
            void ReadException(Exception ex)
            {
                error += string.Format("{0}|{1}|{2}", ex.Message, ex.StackTrace, ex.InnerException);
                if (ex.InnerException != null)
                {
                    ReadException(ex.InnerException);
                }
            }
            ReadException(exception);

            var usrName = SSOClient.getUser(HttpContextCore.Current)?.UserName;
            SaveSysLog(error, LogLevelEnum.Error, HttpContextCore.Current.Request.Path, usrName, exception, "");



            //StringBuilder sb = new StringBuilder();
            //sb.Append(ex.Message);
            //sb.Append(ex.StackTrace);
            //sb.Append(ex.Source);
            //string Description = "Message||" + ex.Message + "||StackTrace||" + ex.StackTrace + "||Source||" + ex.Source;
            //SaveLog("err_log", sb.ToString());

            //try
            //{
            //    //var currentUser = new JwtUser
            //    //{
            //    //    UserNo = "System",
            //    //    UserName = "系统"
            //    //};
            //    string ip = "";
            //    //if (SSOClient.IsLogin)
            //    //{
            //    // var currentUser = SSOClient.User;
            //    ip = HttpContextCore.Current.Request.Headers["X-Forwarded-For"].FirstOrDefault() ?? HttpContextCore.Current.Connection.RemoteIpAddress.ToString();
            //    // }

            //    SysLog model = new SysLog
            //    {
            //        UserNo = "",//currentUser.UserNo,
            //        UserName = "",//currentUser.UserName,
            //        IPAddress = ip,
            //        CreatedOn = DateTime.Now,
            //        CreatedBy = "",// currentUser.UserNo,
            //        Type = "错误日志",
            //        Title = "程序异常",
            //        RecordStatus = false,
            //        Remarks = Description
            //    };
            //    //SqlHelper.InsertSql(model, new string[] { "LogID" });
            //    DataType DbType = EnumHelper.StringConvertToEnum<DataType>(StaticClass.DbTypeStr ?? "SqlServer");
            //    // var list = DbType.DB().Select<SysLogNew>().Where(o => o.ID == "f6bca4d9-2ab6-4ea1-a19b-309ac522ee76").ToList();
            //    var count = DbType.DB().Insert<SysLog>().AppendData(model).ExecuteAffrows();


            //}
            //catch (Exception e) { SaveLog("savelog_err", e); }
        }


        /// <summary>
        /// 操作日志
        /// </summary>
        /// <param name="apiUrl"></param>
        public static void SaveOperaLog(HttpContext context, SysOperationLogTypeEnum sysOperationLogTypeEnum, SysUser sysUser = null, long mis = 0, string requestParams = "")
        {
            string path = context.Request.Path.Value;
            SysUser user = sysUser == null ? SSOClient.getUser(context) : sysUser;
            string method = context.Request.Method;

            string ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault() ?? context.Connection.RemoteIpAddress.ToString();

            SysOperationLog sysOperationLogModel = new SysOperationLog
            {
                IPAddress = ip,
                CreatedBy = user?.UserID.ToString(),
                CreatedOn = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
                ID = Guid.NewGuid().ToString(),
                Method = method,
                RequestParams = requestParams,
                RequestPath = path,
                UserName = user?.UserName,
                RecordStatus = false,
                TakeUpTime = mis,
                LogType = (int)sysOperationLogTypeEnum
            };

            Task.Run(() =>
            {
                try
                {

                    DataType DbType = EnumHelper.StringConvertToEnum<DataType>(StaticClass.DbTypeStr ?? "SqlServer");
                    string tableName = "SysOperationLog";

                    DbType.DB().GetGuidRepository<SysOperationLog>(null, oldName => tableName).Insert(sysOperationLogModel);
                }
                catch (Exception e) { SaveLog("savelog_err", e); }
            });
        }

        public static void SaveLog(string logName, Exception ex)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(ex.Message);
            sb.Append(ex.StackTrace);
            sb.Append(ex.Source);
            SaveLog(logName, sb.ToString());
        }

        public static void SaveLog(string logName, string msg, params string[] para)
        {
            try
            {

                if (!Directory.Exists(HttpContextCore.Env.ContentRootPath + "/logs/"))
                    Directory.CreateDirectory(HttpContextCore.Env.ContentRootPath + "/logs/");

                DateTime now = DateTime.Now;
                string LogFile = HttpContextCore.Env.ContentRootPath + "/logs/" + logName + "_" + now.ToString("yyyy-MM-dd") + ".log";
                lock (lockKey)
                {
                    using (FileStream fs = new FileStream(LogFile, FileMode.Append, FileAccess.Write))
                    {
                        byte[] datetimefile = Encoding.Default.GetBytes(logName + "_" + now.ToString("yyyy-MM-dd HH:mm:ss.fff") + ":\r\n");
                        fs.Write(datetimefile, 0, datetimefile.Length);
                        if (!String.IsNullOrEmpty(msg))
                        {
                            byte[] data = Encoding.Default.GetBytes((para.Length > 0 ? string.Format(msg, para) : msg) + "\r\n==========================================\r\n");
                            fs.Write(data, 0, data.Length);
                        }
                        fs.Flush();
                    }
                }
            }
            catch
            { }
        }
        /// <summary>
        /// 保存系统日志
        /// </summary>
        /// <param name="content">日志内容</param>
        /// <param name="level">日志级别</param>
        /// <param name="path">接口路径</param>
        /// <param name="opUser">操作人</param>
        /// <param name="action">动作标识</param>
        public static void SaveSysLog(string content, LogLevelEnum level, string path, string opUser, Exception exception, string action = "")
        {
            var item = new SysLogNew();
            item.ID = Guid.NewGuid().ToString();
            item.ProjectName = ProjectName;
            item.Env = (short)Env;
            item.ApiPath = path;
            item.Level = (short)level;
            item.ActionTag = action;
            item.Content = content;
            item.CreatedOn = DateTime.Now;
            item.CreatedBy = opUser;
            item.RecordStatus = 0;
            item.ExceptionType = exception.GetType().ToString();
            var message = JsonConvert.SerializeObject(item);

            SaveLogByType(message);

        }

        public static void SaveLogByType(string message)
        {
            //判断存储方式
            if ((saveType & LogSaveTypeEnum.Console) != 0)
            {
                Console.WriteLine(message);
            }
            if ((saveType & LogSaveTypeEnum.File) != 0)
            {
                SaveLog("syslog", message);
            }
            if ((saveType & LogSaveTypeEnum.DB) != 0)
            {
                DataType DbType = EnumHelper.StringConvertToEnum<DataType>(StaticClass.DbTypeStr ?? "SqlServer");

                string tableName = "SysLogNew";

                //DbType.DB().GetGuidRepository<SysLogNew>(null, oldName => tableName).Insert(JsonConvert.DeserializeObject<SysLogNew>(message));

                //DataType DbType = EnumHelper.StringConvertToEnum<DataType>(StaticClass.DbTypeStr ?? "SqlServer");
                //var count = DbType.DB().Insert<SysLogNew>().AppendData(JsonConvert.DeserializeObject<SysLogNew>(message)).ExecuteAffrows();

                //BaseFreeSqlDao<SysLogNew> logDao = new BaseFreeSqlDao<SysLogNew>();
                ////测试更新
                //var mod = JsonConvert.DeserializeObject<SysLogNew>(message);
                //mod.ID = "123455";
                // var isupd= logDao.Update(mod, o => o.ID == "8d4f98d4-f2d0-4a44-90ad-39c0d1cc31d0");
                ////测试删除
                //var isDel = logDao.Delete(new { CreatedOn = "2020-09-08 19:58:18.317", RecordStatus = 0 });
                //baseSqlDao(JsonConvert.DeserializeObject<SysLogNew>(message));
            }
        }
        /// <summary>
        /// 开启保存日志线程
        /// </summary>
        public static void StartSaveLogThread()
        {
        }
    }
}